package com.cencat.route.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cencat.route.entity.RouteInvoice;
import com.cencat.route.mapper.RouteInvoiceMapper;
import com.cencat.route.service.RouteInvoiceService;
import com.cencat.route.vo.RouteInvoiceQueryVO;
import com.cencat.route.vo.RouteInvoiceStatisticsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 路线发票服务实现类
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RouteInvoiceServiceImpl extends ServiceImpl<RouteInvoiceMapper, RouteInvoice> implements RouteInvoiceService {

    private final RouteInvoiceMapper routeInvoiceMapper;

    @Override
    public Page<RouteInvoice> selectRouteInvoicePage(Page<RouteInvoice> page, RouteInvoiceQueryVO query) {
        return routeInvoiceMapper.selectRouteInvoicePage(page, query);
    }

    @Override
    public List<RouteInvoice> selectRouteInvoiceList(RouteInvoiceQueryVO query) {
        return routeInvoiceMapper.selectRouteInvoiceList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateInvoiceStatus(List<Long> ids, String status, Long updatedBy) {
        try {
            return routeInvoiceMapper.batchUpdateInvoiceStatus(ids, status, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新发票状态失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新发票状态失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateInvoiceType(List<Long> ids, String invoiceType, Long updatedBy) {
        try {
            return routeInvoiceMapper.batchUpdateInvoiceType(ids, invoiceType, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新发票类型失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新发票类型失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateTaxRate(List<Long> ids, BigDecimal taxRate, Long updatedBy) {
        try {
            return routeInvoiceMapper.batchUpdateTaxRate(ids, taxRate, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新税率失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新税率失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateInvoiceAmount(List<Long> ids, BigDecimal invoiceAmount, Long updatedBy) {
        try {
            return routeInvoiceMapper.batchUpdateInvoiceAmount(ids, invoiceAmount, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新发票金额失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新发票金额失败", e);
        }
    }

    @Override
    public RouteInvoiceStatisticsVO getRouteInvoiceStatistics() {
        try {
            return routeInvoiceMapper.getRouteInvoiceStatistics();
        } catch (Exception e) {
            log.error("获取路线发票统计信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取路线发票统计信息失败", e);
        }
    }

    @Override
    public String analyzeInvoiceTax(Long invoiceId) {
        try {
            return routeInvoiceMapper.analyzeInvoiceTax(invoiceId);
        } catch (Exception e) {
            log.error("分析发票税务失败: {}", e.getMessage(), e);
            throw new RuntimeException("分析发票税务失败", e);
        }
    }

    @Override
    public String checkInvoiceCompliance(Long invoiceId) {
        try {
            return routeInvoiceMapper.checkInvoiceCompliance(invoiceId);
        } catch (Exception e) {
            log.error("检查发票合规性失败: {}", e.getMessage(), e);
            throw new RuntimeException("检查发票合规性失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getPendingInvoices(Integer limit) {
        try {
            return routeInvoiceMapper.getPendingInvoices(limit);
        } catch (Exception e) {
            log.error("获取待处理发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取待处理发票列表失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getIssuedInvoices(Integer limit) {
        try {
            return routeInvoiceMapper.getIssuedInvoices(limit);
        } catch (Exception e) {
            log.error("获取已开具发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取已开具发票列表失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getCancelledInvoices(Integer limit) {
        try {
            return routeInvoiceMapper.getCancelledInvoices(limit);
        } catch (Exception e) {
            log.error("获取已作废发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取已作废发票列表失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getRedInvoices(Integer limit) {
        try {
            return routeInvoiceMapper.getRedInvoices(limit);
        } catch (Exception e) {
            log.error("获取红字发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取红字发票列表失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getHighAmountInvoices(BigDecimal minAmount, Integer limit) {
        try {
            return routeInvoiceMapper.getHighAmountInvoices(minAmount, limit);
        } catch (Exception e) {
            log.error("获取高金额发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取高金额发票列表失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getRecentInvoices(Integer days, Integer limit) {
        try {
            return routeInvoiceMapper.getRecentInvoices(days, limit);
        } catch (Exception e) {
            log.error("获取最近发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取最近发票列表失败", e);
        }
    }

    @Override
    public List<RouteInvoice> getOverdueInvoices(Integer days, Integer limit) {
        try {
            return routeInvoiceMapper.getOverdueInvoices(days, limit);
        } catch (Exception e) {
            log.error("获取逾期发票列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取逾期发票列表失败", e);
        }
    }

    @Override
    public boolean checkInvoiceExists(Long id) {
        try {
            return routeInvoiceMapper.checkInvoiceExists(id) > 0;
        } catch (Exception e) {
            log.error("检查发票是否存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public boolean checkInvoiceNumberExists(String invoiceNumber, Long excludeId) {
        try {
            return routeInvoiceMapper.checkInvoiceNumberExists(invoiceNumber, excludeId) > 0;
        } catch (Exception e) {
            log.error("检查发票号码是否存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean issueInvoice(Long invoiceId, String invoiceNumber, Long issuedBy) {
        try {
            return routeInvoiceMapper.issueInvoice(invoiceId, invoiceNumber, issuedBy) > 0;
        } catch (Exception e) {
            log.error("开具发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("开具发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelInvoice(Long invoiceId, String cancelReason, Long cancelledBy) {
        try {
            return routeInvoiceMapper.cancelInvoice(invoiceId, cancelReason, cancelledBy) > 0;
        } catch (Exception e) {
            log.error("作废发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("作废发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean redInvoice(Long invoiceId, String redReason, Long redBy) {
        try {
            return routeInvoiceMapper.redInvoice(invoiceId, redReason, redBy) > 0;
        } catch (Exception e) {
            log.error("红冲发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("红冲发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditInvoice(Long invoiceId, String auditStatus, String auditNotes, Long auditedBy) {
        try {
            return routeInvoiceMapper.auditInvoice(invoiceId, auditStatus, auditNotes, auditedBy) > 0;
        } catch (Exception e) {
            log.error("审核发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("审核发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean verifyInvoice(Long invoiceId, String verificationStatus, String verificationNotes, Long verifiedBy) {
        try {
            return routeInvoiceMapper.verifyInvoice(invoiceId, verificationStatus, verificationNotes, verifiedBy) > 0;
        } catch (Exception e) {
            log.error("认证发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("认证发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceInfo(Long invoiceId, String buyerName, String buyerTaxNumber, String sellerName, String sellerTaxNumber, Long updatedBy) {
        try {
            return routeInvoiceMapper.updateInvoiceInfo(invoiceId, buyerName, buyerTaxNumber, sellerName, sellerTaxNumber, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新发票信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新发票信息失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceAmount(Long invoiceId, BigDecimal invoiceAmount, BigDecimal taxAmount, BigDecimal totalAmount, Long updatedBy) {
        try {
            return routeInvoiceMapper.updateInvoiceAmount(invoiceId, invoiceAmount, taxAmount, totalAmount, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新发票金额失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新发票金额失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceDate(Long invoiceId, String invoiceDate, String dueDate, Long updatedBy) {
        try {
            return routeInvoiceMapper.updateInvoiceDate(invoiceId, invoiceDate, dueDate, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新发票日期失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新发票日期失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceNotes(Long invoiceId, String invoiceNotes, String remarks, Long updatedBy) {
        try {
            return routeInvoiceMapper.updateInvoiceNotes(invoiceId, invoiceNotes, remarks, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新发票备注失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新发票备注失败", e);
        }
    }

    @Override
    public String generateInvoiceReport(Long invoiceId, String reportType) {
        try {
            return routeInvoiceMapper.generateInvoiceReport(invoiceId, reportType);
        } catch (Exception e) {
            log.error("生成发票报告失败: {}", e.getMessage(), e);
            throw new RuntimeException("生成发票报告失败", e);
        }
    }

    @Override
    public String exportInvoiceData(RouteInvoiceQueryVO query, String exportFormat) {
        try {
            return routeInvoiceMapper.exportInvoiceData(query, exportFormat);
        } catch (Exception e) {
            log.error("导出发票数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("导出发票数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importInvoiceData(String importData, Long importedBy) {
        try {
            return routeInvoiceMapper.importInvoiceData(importData, importedBy);
        } catch (Exception e) {
            log.error("导入发票数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("导入发票数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchProcessInvoices(List<Long> invoiceIds, String processType, Long processedBy) {
        try {
            return routeInvoiceMapper.batchProcessInvoices(invoiceIds, processType, processedBy) > 0;
        } catch (Exception e) {
            log.error("批量处理发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量处理发票失败", e);
        }
    }

    @Override
    public String getInvoiceRecommendations(Long invoiceId) {
        try {
            return routeInvoiceMapper.getInvoiceRecommendations(invoiceId);
        } catch (Exception e) {
            log.error("获取发票推荐失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取发票推荐失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean recordInvoiceEvent(Long invoiceId, String eventType, String eventDescription, Long recordedBy) {
        try {
            return routeInvoiceMapper.recordInvoiceEvent(invoiceId, eventType, eventDescription, recordedBy) > 0;
        } catch (Exception e) {
            log.error("记录发票事件失败: {}", e.getMessage(), e);
            throw new RuntimeException("记录发票事件失败", e);
        }
    }

    @Override
    public String getInvoiceAlternatives(Long invoiceId, Integer maxAlternatives) {
        try {
            return routeInvoiceMapper.getInvoiceAlternatives(invoiceId, maxAlternatives);
        } catch (Exception e) {
            log.error("获取发票替代方案失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取发票替代方案失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean optimizeInvoice(Long invoiceId, String optimizationType, Long optimizedBy) {
        try {
            return routeInvoiceMapper.optimizeInvoice(invoiceId, optimizationType, optimizedBy) > 0;
        } catch (Exception e) {
            log.error("优化发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("优化发票失败", e);
        }
    }

    @Override
    public String validateInvoice(Long invoiceId) {
        try {
            return routeInvoiceMapper.validateInvoice(invoiceId);
        } catch (Exception e) {
            log.error("验证发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("验证发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean archiveInvoice(Long invoiceId, String archiveReason, Long archivedBy) {
        try {
            return routeInvoiceMapper.archiveInvoice(invoiceId, archiveReason, archivedBy) > 0;
        } catch (Exception e) {
            log.error("归档发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("归档发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean restoreInvoice(Long invoiceId, Long restoredBy) {
        try {
            return routeInvoiceMapper.restoreInvoice(invoiceId, restoredBy) > 0;
        } catch (Exception e) {
            log.error("恢复发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("恢复发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cloneInvoice(Long sourceInvoiceId, String newInvoiceNumber, Long clonedBy) {
        try {
            return routeInvoiceMapper.cloneInvoice(sourceInvoiceId, newInvoiceNumber, clonedBy) > 0;
        } catch (Exception e) {
            log.error("克隆发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("克隆发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean mergeInvoices(List<Long> invoiceIds, String newInvoiceNumber, Long mergedBy) {
        try {
            return routeInvoiceMapper.mergeInvoices(invoiceIds, newInvoiceNumber, mergedBy) > 0;
        } catch (Exception e) {
            log.error("合并发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("合并发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean splitInvoice(Long invoiceId, String splitConfig, Long splitBy) {
        try {
            return routeInvoiceMapper.splitInvoice(invoiceId, splitConfig, splitBy) > 0;
        } catch (Exception e) {
            log.error("拆分发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("拆分发票失败", e);
        }
    }

    @Override
    public String calculateInvoiceTax(Long invoiceId) {
        try {
            return routeInvoiceMapper.calculateInvoiceTax(invoiceId);
        } catch (Exception e) {
            log.error("计算发票税额失败: {}", e.getMessage(), e);
            throw new RuntimeException("计算发票税额失败", e);
        }
    }

    @Override
    public BigDecimal estimateInvoiceValue(Long invoiceId) {
        try {
            return routeInvoiceMapper.estimateInvoiceValue(invoiceId);
        } catch (Exception e) {
            log.error("预估发票价值失败: {}", e.getMessage(), e);
            throw new RuntimeException("预估发票价值失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceStatistics(Long invoiceId, Long updatedBy) {
        try {
            return routeInvoiceMapper.updateInvoiceStatistics(invoiceId, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新发票统计信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新发票统计信息失败", e);
        }
    }

    @Override
    public String getInvoiceHistory(Long invoiceId) {
        try {
            return routeInvoiceMapper.getInvoiceHistory(invoiceId);
        } catch (Exception e) {
            log.error("获取发票历史失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取发票历史失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean notifyInvoiceUpdate(Long invoiceId, String notificationType, String message, Long notifiedBy) {
        try {
            return routeInvoiceMapper.notifyInvoiceUpdate(invoiceId, notificationType, message, notifiedBy) > 0;
        } catch (Exception e) {
            log.error("通知发票更新失败: {}", e.getMessage(), e);
            throw new RuntimeException("通知发票更新失败", e);
        }
    }

    @Override
    public String getInvoiceMetrics(Long invoiceId, String metricsType) {
        try {
            return routeInvoiceMapper.getInvoiceMetrics(invoiceId, metricsType);
        } catch (Exception e) {
            log.error("获取发票指标失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取发票指标失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean escalateInvoice(Long invoiceId, String escalationReason, Long escalatedBy) {
        try {
            return routeInvoiceMapper.escalateInvoice(invoiceId, escalationReason, escalatedBy) > 0;
        } catch (Exception e) {
            log.error("升级发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("升级发票失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deescalateInvoice(Long invoiceId, String deescalationReason, Long deescalatedBy) {
        try {
            return routeInvoiceMapper.deescalateInvoice(invoiceId, deescalationReason, deescalatedBy) > 0;
        } catch (Exception e) {
            log.error("降级发票失败: {}", e.getMessage(), e);
            throw new RuntimeException("降级发票失败", e);
        }
    }

}